package org.rency.crawler.fetch.helper;

import java.nio.charset.Charset;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.rency.common.utils.domain.Extension;
import org.rency.crawler.common.CrawlerConstants;
import org.rency.crawler.common.enums.HttpMethod;
import org.rency.crawler.common.helper.GeneratorHelper;
import org.rency.crawler.dal.entity.FetchPageDO;
import org.rency.crawler.domain.FetchExtension;
import org.rency.crawler.domain.FetchHost;
import org.rency.crawler.domain.FetchRequest;
import org.rency.crawler.domain.queue.FetchQueue;
import org.rency.crawler.domain.vo.DocDomain;
import org.springframework.data.util.Pair;

/**
 * 名称:DomainBuilder
 * 描述:${TODO}
 *
 * @author:rency
 * @version:V1.0.0
 * @JDK 1.8
 * @since 2017/11/22 22:15
 */
public class BuilderHelper {

  /**
   * 构建域名领域
   * @param hostName
   * @param hostNo
   * @param hostAddress
   * @param fetchIntervalTime 访问间隔
   * @param hostPriority
   * @return
   */
  public static FetchHost build(String hostNo,String hostName,String hostAddress,long fetchIntervalTime,long hostPriority) {
    if(StringUtils.isBlank(hostAddress)){
      return null;
    }
    FetchHost domain = new FetchHost();
    domain.setHostNo(StringUtils.isBlank(hostNo) ? GeneratorHelper.genHashCode(hostAddress) : hostNo);
    domain.setHostName(StringUtils.isNotEmpty(hostName) ? hostName : hostAddress);
    domain.setFetchIntervalTime(fetchIntervalTime);
    domain.setHostAddress(hostAddress);
    domain.setHostPriority(hostPriority);
    domain.setLastedFetchTime(LocalDateTime.now());
    domain.setGmtCreate(LocalDateTime.now());
    domain.setGmtUpdate(domain.getGmtCreate());
    return domain;
  }

  /**
   * 构建抓取队列领域
   * @param fetchUri 请求地址
   * @param hostAddr 域名
   * @param httpMethod 请求方法
   * @param parameter 请求参数
   * @param fetchDepth 抓取深度
   * @param maxRetryTimes 最大重试次数
   * @param remark 备注
   * @return
   */
  public static FetchQueue build(String fetchUri, String hostAddr, HttpMethod httpMethod, Extension parameter, int fetchDepth,int maxRetryTimes,String remark){
    if(StringUtils.isBlank(fetchUri)){
      return null;
    }
    FetchQueue domain = new FetchQueue();
    domain.setHttpMethod(httpMethod);
    domain.setFetchNo(GeneratorHelper.genHashCode(fetchUri));
    domain.setFetchUri(fetchUri);
    domain.setFetchHost(GeneratorHelper.genHashCode(hostAddr));
    domain.setHostAddr(hostAddr);
    domain.setParameter(parameter);
    domain.setGmtCreate(LocalDateTime.now());
    domain.setGmtUpdate(domain.getGmtCreate());
    FetchExtension extension = new FetchExtension();
    extension.setMachineIP(CrawlerConstants.LOCATION_MACHINE_IP);
    extension.setRemark(remark);//StringUtil.abbreviate(memo, CrawlerDict.EXTENSION_COLUMN_LENGTH)
    extension.setMaxRetryTimes(maxRetryTimes);
    extension.setFetchDepth(fetchDepth);
    extension.setLastedFetchTime(null);
    domain.setExtension(extension);
    return domain;
  }

  /**
   * 构建页面对象领域
   * </br>Created on 2016年7月2日
   * @param docNo 编号<p>和队列编号一致</p>
   * @param docUri 文档URI
   * @param title 文档标题
   * @param description 文档描述
   * @param keywords 文档关键字
   * @param charset 文档字符集
   * @param html html内容
   * @param text 文本内容
   * @return
   */
  public static DocDomain build(String docNo, String docUri, String title, String description, String keywords, Charset charset, byte[] html, byte[] text){
    DocDomain domain = new DocDomain();
    domain.setCharset(charset);
    domain.setDocNo(docNo);
    domain.setFinger((html==null || html.length==0) ? null : GeneratorHelper.genHashCode(html));
    domain.setTitle(title);
    domain.setDocUri(docUri);
    //内容(文本)
    domain.setText(text);
    //html
    domain.setHtml(html);
    domain.setDescription(description);
    domain.setKeywords(keywords);
    domain.setGmtCreate(LocalDateTime.now());
    domain.setGmtUpdate(domain.getGmtCreate());
    return domain;
  }

  public static List<FetchPageDO> convertDoc(Collection<DocDomain> docs){
    if(CollectionUtils.isEmpty(docs)){
      return new ArrayList<>(0);
    }
    List<FetchPageDO> resultList = new ArrayList<>(docs.size());
    for(DocDomain doc : docs){
      resultList.add(BuilderHelper.convertDoc(doc));
    }
    return resultList;
  }

  public static FetchPageDO convertDoc(DocDomain doc){
    if(doc == null){
      return null;
    }
    FetchPageDO page = new FetchPageDO();
    page.setHtml(doc.getHtml());
    page.setCharset(doc.getCharset() == null ? CrawlerConstants.DEFAULT_CHARSET : doc.getCharset().name());
    page.setDescription(doc.getDescription());
    page.setDocNo(doc.getDocNo());
    page.setKeywords(doc.getKeywords());
    page.setFinger(doc.getFinger());
    page.setTitle(doc.getTitle());
    page.setText(doc.getText());
    page.setDocUri(doc.getDocUri());
    page.setGmtCreate(LocalDateTime.now());
    page.setGmtUpdate(page.getGmtCreate());
    return page;
  }

  public static Pair<FetchRequest, FetchExtension> build(FetchQueue queue){
    if(queue == null){
      return Pair.of(null,null);
    }
    FetchRequest request = new FetchRequest();
    request.setFetchHost(queue.getFetchHost());
    request.setFetchNo(queue.getFetchNo());
    request.setFetchUri(queue.getFetchUri());
    request.setHttpMethod(queue.getHttpMethod());
    request.setParameter(queue.getParameter());
    request.setHostAddr(queue.getHostAddr());
    FetchExtension fetchExt = queue.getExtension();
    return Pair.of(request,fetchExt);
  }

  /**
   * 获取抓取队列领域
   * @param carrier
   * @return
   */
  public static FetchQueue build(FetchCarrier carrier){
    if(carrier == null || carrier.getRequest() == null){
      return null;
    }
    FetchQueue domain = new FetchQueue();
    domain.setFetchNo(carrier.getRequest().getFetchNo());
    domain.setParameter(carrier.getRequest().getParameter());
    domain.setFetchHost(carrier.getRequest().getFetchHost());
    domain.setFetchUri(carrier.getRequest().getFetchUri());
    domain.setHttpMethod(carrier.getRequest().getHttpMethod());
    domain.setHostAddr(carrier.getRequest().getHostAddr());
    domain.setExtension(carrier.getExtension());
    return domain;
  }
}
